// Modules to control application life and create native browser window
const {
  app,
  BrowserWindow,
  utilityProcess,
  MessageChannelMain,
  ipcMain,
  Menu,
} = require("electron");
const path = require("path");
const os = require("os");

function createWindow() {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, "preload/preload.js"),
      webSecurity: false,
      sandbox: false,
      nodeIntegration: false,
      nodeIntegrationInWorker: false,
    },
  });

  // and load the index.html of the app.
  mainWindow.loadFile(path.join(__dirname, "..", "..", "index.html"));

  // // 移除菜单
  // mainWindow.setMenu(null);

  // // 或者移除所有窗口的菜单
  // Menu.setApplicationMenu(null);

  // Open the DevTools.
  mainWindow.webContents.openDevTools();
  return mainWindow;
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
  const mainWindow = createWindow();

  ipcMain.handle("getLANIP", () => {
    const interfaces = os.networkInterfaces();

    for (const name in interfaces) {
      const ifaceList = interfaces[name];

      for (const iface of ifaceList) {
        // 确保是IPv4地址并且不是回环地址
        if (iface.family === "IPv4" && !iface.internal) {
          return iface.address;
        }
      }
    }

    return null;
  });
  const childArray = [];

  ipcMain.on("port-download", (event, message) => {
    handleChildProcess({ event, message, index: 0 });
  });

  ipcMain.handle("end-download", () => {
    return new Promise((resolve) => {
      console.log("kill child download");

      const child = childArray[0];

      if (child) {
        const { port1, port2 } = new MessageChannelMain();

        port2.on("message", (message) => {
          console.log("end-download message", message);

          child.kill();
          resolve(message);
        });
        port2.start();
        child.postMessage({ type: "closeDatabase" }, [port1]);
      }
    });
  });

  ipcMain.on("port-upload", (event, message) => {
    handleChildProcess({ event, message, index: 1 });
  });

  ipcMain.handle("end-upload", () => {
    return new Promise((resolve) => {
      console.log("kill child upload");
      const child = childArray[1];

      if (child) {
        const { port1, port2 } = new MessageChannelMain();

        port2.on("message", (message) => {
          console.log("end-upload message", message);

          child.kill();
          resolve(message);
        });
        port2.start();
        child.postMessage({ type: "closeDatabase" }, [port1]);
      }
    });
  });
  function handleChildProcess({ event, message, index }) {
    const [port] = event.ports;
    let child = childArray[index];

    if (!child) {
      child = utilityProcess.fork(path.join(__dirname, "subprocess.js"));
      childArray[index] = child;
      child.on("exit", (...reset) => {
        childArray[index] = null;
        console.log("process exit", "index: " + index, reset);
      });
    }
    child.postMessage(message, [port]);
  }

  app.on("activate", function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
});

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on("window-all-closed", function () {
  if (process.platform !== "darwin") app.quit();
});

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
